package com.jacen.fzxs.controller;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FilenameFilter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.jacen.fzxs.util.DateUtils;
import com.jacen.fzxs.util.OSUtils;

@Controller
public class SystemController extends BaseController implements FilenameFilter {
	
	private static final Logger logger = LoggerFactory.getLogger(SystemController.class);

	@RequestMapping(value = "/system/monitor.do")
	public String systemMonitor(ModelMap modelMap) {
		Double maxMemory = Runtime.getRuntime().maxMemory() / (1024.0 * 1024);
		Double totalMemory = Runtime.getRuntime().totalMemory() / (1024.0 * 1024);
		Double freeMemory = Runtime.getRuntime().freeMemory() / (1024.0 * 1024);
		String basePath = System.getProperty("catalina.base") + File.separator+"logs";
		List<FileInfo> logFileInfos = getFiles(basePath,"fzxs");
		modelMap.addAttribute("maxMemory", maxMemory);
		modelMap.addAttribute("totalMemory", totalMemory);
		modelMap.addAttribute("freeMemory", freeMemory);
		modelMap.addAttribute("logFileInfos", logFileInfos);
		return "system/monitor";
	}

	@RequestMapping(value = "/system/backup.do")
	public String backup(ModelMap modelMap) {
		String basePath = System.getProperty("catalina.base") + File.separator+ "dbbackup";
		File baseFile = new File(basePath);
		if (!baseFile.exists()) {
			baseFile.mkdir();
		}
		List<FileInfo> backupFileInfos = getFiles(basePath,"fzxs");
		modelMap.addAttribute("backupFileInfos", backupFileInfos);
		return "system/backup";
	}

	@RequestMapping(value = "/system/dbbackup.do",method = RequestMethod.POST)
	public String dbbackup(ModelMap modelMap) {
		String basePath = System.getProperty("catalina.base") + File.separator+"dbbackup";
		try {
			OSUtils.getMysqlDbBackupCmd(basePath + File.separator+ "fzxs_" + DateUtils.date2Str(new Date(), "yyyyMMddHHmmss") + ".sql");
				Thread.sleep(2000);
		} catch (Exception e) {
			logger.info("备份文件异常:" + e.getMessage());
		}
		return "redirect:/system/backup.do";
	}
	
	@RequestMapping(value = "/system/delete.do")
	public String delete(ModelMap modelMap,String fileName,String type) {
		String basePath = System.getProperty("catalina.base") +File.separator+"logs";
		if("db".equals(type)){
			basePath = System.getProperty("catalina.base") + File.separator+"dbbackup";
		}
		String osName = System.getProperty("os.name");  
		logger.info("operation system name is :"+ osName);
		String cmd = OSUtils.getDelCmd(basePath + File.separator+ fileName);
		logger.info("cmd is :"+ cmd);
		try {
				Runtime.getRuntime().exec(cmd);
				Thread.sleep(300);
		} catch (Exception e) {
			logger.info("删除文件异常:" + e.getMessage());
		}
		if("db".equals(type))
			return "redirect:/system/backup.do";
		return "redirect:/system/monitor.do";
	}

	private List<FileInfo> getFiles(String basePath,String prefix) {
		File file = new File(basePath);
		File[] logFiles = file.listFiles(this);
		List<FileInfo> fileInfos = new ArrayList<FileInfo>();
		if (logFiles != null) {
			FileInfo logFileInfo = null;
			for (int i = 0; i < logFiles.length; i++) {
				if(!logFiles[i].getName().startsWith(prefix))continue;
				logFileInfo = new FileInfo(logFiles[i]);
				fileInfos.add(logFileInfo);
			}
		}
		return fileInfos;
	}

	@RequestMapping(value = "/system/download.do")
	public void downloadLog(HttpServletResponse response, String fileName,String type) {
		String basePath = "";
		if("db".equals(type)){
			basePath = System.getProperty("catalina.base") + "/dbbackup";
		}else{
			basePath = System.getProperty("catalina.base") + "/logs";
		}
		String targetFilePath = basePath + "/" + fileName;
		logger.info(targetFilePath);
		InputStream in = null;
		OutputStream out = null;
		try {
			response.reset();
			File file = new File(targetFilePath);
			if (!file.exists()) {
				logger.info("文件不存在:" + targetFilePath);
			}
			response.setHeader("Content-disposition", "attachment;filename=" + new String(fileName.getBytes(), "ISO8859-1")); // 必须经过ISO8859-1转换，否则无法输出
			response.setContentType("application/x-download");
			OutputStream os = response.getOutputStream();
			int bufferSize = 100 * 1024 * 8;
			in = new BufferedInputStream(new FileInputStream(targetFilePath), bufferSize);
			out = new BufferedOutputStream(os, bufferSize);
			byte[] buffer = new byte[bufferSize];
			int len = 0;
			while ((len = in.read(buffer)) > 0) {
				out.write(buffer, 0, len);
			}
			out.flush();
		} catch (Exception e) {
		} finally {
			if (null != in) {
				try {
					in.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
			if (null != out) {
				try {
					out.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
	}

	public static class FileInfo {
		private String fileName;
		private Double size;

		public FileInfo() {

		}

		public FileInfo(File file) {
			this.fileName = file.getName();
			this.size = file.length() / (1024.0 * 1024);
		}

		public String getFileName() {
			return fileName;
		}

		public void setFileName(String fileName) {
			this.fileName = fileName;
		}

		public Double getSize() {
			return size;
		}

		public void setSize(Double size) {
			this.size = size;
		}
	}

	@Override
	public boolean accept(File dir, String name) {
		return true;
	}
	
	public static void main(String[] args) {
		Map<String,String> map = System.getenv();
    Set<Map.Entry<String,String>> entries = map.entrySet();
    for (Map.Entry<String, String> entry : entries) {
    	logger.info(entry.getKey() + ":" + entry.getValue());
    }
	}

}
